/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import java.util.Arrays;

/**
 * Simple implementation of collection interface.
 * @author Dmitri Paziy
 */
public class SimpleCollection<T> implements Collection<T> {

    private Object[] collection;
    private int size = 0;                      //current amount of elements
    private static final String CANT_ADD = "Can't add null element";
    private static final String ILLEGAL_CAPACITY = "Illegal capacity";
    public final int initialCapacity = 16;

    /**
     * Creates new collection with specified initial capacity.
     * @param capacity Capacity of collection.
     * @throws IllegalArgumentException if collections initial capacity was 
     * specified as negative.
     */
    public SimpleCollection(int capacity) {
        if (capacity < 0) {
            throw new IllegalArgumentException(ILLEGAL_CAPACITY + capacity);
        }

        collection = new Object[capacity];
    }

    public SimpleCollection() {
        collection = new Object[initialCapacity];
    }

    /**
     * Adds new item to collection. If current amount of items equals capacity
     * then capacity of collection is doubled.
     * @param item New item
     * @throws NullPointerException If new item is null.
     */
    @Override
    public void add(T item) {
        if (item == null) {
            throw new NullPointerException(CANT_ADD);
        }

        if (size == collection.length) {
            doubleCapacity();
        }

        collection[size++] = item;
    }

    /**
     * Removes item on specified index. Note that index of item is not checked.
     * @param index Index of item to be removed
     * @return Removed item
     */
    @Override
    public T remove(int index) {
        rangeCheck(index);
        --size;
        return (T) collection[index];
    }

    /**
     * Gets item on specified index. Note that index of item is not checked.
     * @param index Index of item
     * @return Item on specified position.
     */
    @Override
    public T get(int index) {
        rangeCheck(index);

        return (T) collection[index];
    }

    /**
     * Gets current amount of elements in collection.
     * @return Amount of items in collection
     */
    @Override
    public int size() {
        return size;
    }

    /**
     * Gives representation of collection as array.
     * @return Array representation.
     */
    @Override
    public Object[] toArray() {
        return Arrays.copyOf(collection, size);
    }

    /**
     * Gets amount of elements that memory was allocated for
     * @return Current maximum amount of elements
     */
    @Override
    public int capacity() {
        return collection.length;
    }

    /**
     * Increases capacity of collection in two times.
     */
    private void doubleCapacity() {
        collection = Arrays.copyOf(collection, collection.length * 2);
    }

    /**
     * Checks range for correctness.
     * @param index index to be checked
     * @throws IndexOutOfBoundsException if specified range is not correct.
     */
    private void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }
}
